﻿using Kongt.IServices;
using Kongt.Service;
using System;
using Kongt.Model;
using System.Collections.Generic;
using System.Linq;
using Kongt.IServices.QueryModel;
using System.Data.SqlClient;
using Kongt.ServiceProvider;
using static Kongt.Model.LateFee;
using Kongt.Model.Custom;

namespace Kongt.Service
{

    public class ChargeService : ServiceBase, IService, IDisposable, IChargeService
    {
        public void Create(ChargeInfo ci)
        {
            context.ChargeInfoes.Add(ci);
            context.SaveChanges();
        }
        public void Delete(long id)
        {
            context.ChargeInfoes.Remove(this.Find(id));
            context.SaveChanges();
        }
        public ChargeInfo Find(long id)
        {
            return context.ChargeInfoes.Find(id);
        }
        public decimal GetExtendCharge(ExtendChargeQuery Query)
        {
            return context.ExtendCharges.Where(item =>
                 (Query.WaterTypeId == null || item.WaterTypeId == Query.WaterTypeId)
               && (string.IsNullOrEmpty(Query.HasMeter) || item.HasMeter == Query.HasMeter)
               && (Query.ChargeType == null || item.ChargeType == Query.ChargeType)
               && (string.IsNullOrEmpty(Query.ExtendName) || item.HasMeter == Query.ExtendName)
               && (string.IsNullOrEmpty(Query.FirstArea) || item.HasMeter == Query.FirstArea)
               && (string.IsNullOrEmpty(Query.SecondArea) || item.HasMeter == Query.SecondArea)
               && (string.IsNullOrEmpty(Query.DetailAddress) || item.HasMeter == Query.DetailAddress)
                  ).Sum(item => item.ExtendPrice);
        }
        public PageModel<ChargeInfo> QueryChargeInfoes(ChargeQuery Query)
        {
            var query = context.ChargeInfoes.Where(item =>
                                                          (Query.CustomId == null || item.CustomId == Query.CustomId)
                                                       && (Query.Stat == null || item.State == (int)(Query.Stat.Value))
                                                       && (Query.colectType == null || item.State == (int)(Query.colectType.Value))
                                                       && (Query.CollectDateStart == null || item.ColectMoneyDate >= Query.CollectDateStart)
                                                       && (Query.CollectDateEnd == null || item.ColectMoneyDate <= Query.CollectDateEnd)
                                                       && (Query.Collector == null || item.Collector == Query.Collector)
            )
                                            .OrderBy(item => item.Id);

            var count = query.Count();
            List<ChargeInfo> rows = new List<ChargeInfo>();
            if (count > 0)
            {
                ///为当前查询的计算附加费
                rows = query.Skip(Query.Skip).Take(Query.PageSize).ToList();
                rows.ForEach(item =>
                {
                    item.LateFee = this.GetLateFeeCharge(new LateFeeQuery()
                    {
                        ColetMoneyDate = DateTime.Now,
                        CustomerId = item.CustomId,
                        TotalWaterPrice = item.TotalWaterPrice.Value,
                        ChargeWhichDate = DateTime.Parse(item.ThisTime).AddMonths(-1)
                    });
                    item.TotalPrice = item.TotalWaterPrice + item.ExtendPrice + item.LateFee;
                });
            }

            return new PageModel<ChargeInfo>
            {
                Rows = rows,
                Count = count
            };
        }
        public void Update(ChargeInfo ci)
        {
            var entity = this.Find(ci.Id);
            entity.CustomId = ci.CustomId;
            entity.ChargeName = ci.ChargeName;
            entity.LastTime = ci.LastTime;
            entity.LastMeterShow = ci.LastMeterShow;
            entity.ThisTime = ci.ThisTime;
            entity.ThisMeterShow = ci.ThisMeterShow;
            entity.WaterMuch = ci.WaterMuch;
            entity.WaterPrice = ci.WaterPrice;
            entity.TotalWaterPrice = ci.TotalWaterPrice;
            entity.ExtendPrice = ci.ExtendPrice;
            entity.LateFee = ci.LateFee;
            entity.TotalPrice = ci.TotalPrice;
            entity.State = ci.State;
            entity.CollectMoneyType = ci.CollectMoneyType;
            context.SaveChanges();
        }

        /// <summary>
        /// 获取当前用户上个月成功缴费的信息
        /// </summary>
        /// <param name="CustomerId"></param>
        /// <returns></returns>
        public ChargeInfo GetPrevChargeInfo(long CustomerId, DateTime dt)
        {
            return context.ChargeInfoes.ToList().Where(item => item.CustomId == CustomerId && DateTime.Parse(item.ThisTime).Month == dt.Month - 1).ToList().OrderByDescending(item => DateTime.Parse(item.ThisTime)).FirstOrDefault();
        }


        public decimal GetLadderFeeCharge(LadderFeeQuery Query)
        {
            ///获得用户的用水类型
            var waterTypeId = ServiceFactory.Create<ICustomService>().Find(Query.CustomerId).WaterTypeId;
            var lateFee = context.LadderFees.Where(item => item.WaterTypeId == waterTypeId).Where(item => item.START < Query.WaterMuch && Query.WaterMuch < item.EndTo).FirstOrDefault();
            return lateFee == null ? 0 : lateFee.Price;
        }

        public decimal GetLateFeeCharge(LateFeeQuery Query)
        {
            if (Query.ColetMoneyDate < Query.ChargeWhichDate)
            {
                throw new Exception("交钱月份比缴费月份更早！");
            }
            //比如6月份的水费 7月份缴纳，不需要缴纳滞纳金
            if (Query.ColetMoneyDate.Month == Query.ChargeWhichDate.Month + 1)
            {
                return 0;
            }
            else
            {
                var waterTypeId = ServiceFactory.Create<ICustomService>().Find(Query.CustomerId).WaterTypeId;
                var lateFee = context.LateFees.ToList().Where(item => item.WaterTypeId == waterTypeId //满足用水类型
                                                         && Query.ColetMoneyDate >= item.EffectiveDate //满足缴费时间大于此配置生效的时间
                                                         && item.GetState  //当前配置是生效的
                                                                           //满足有效滞纳天数满足配置的区间
                                                         && ((Query.ColetMoneyDate - (Query.ChargeWhichDate.AddMonths(2).AddDays(-Query.ChargeWhichDate.Day).AddDays(item.StartDayOnMonth - 1))).TotalDays) > int.Parse(item.StartDay)
                                                         && ((Query.ColetMoneyDate - (Query.ChargeWhichDate.AddMonths(2).AddDays(-Query.ChargeWhichDate.Day).AddDays(item.StartDayOnMonth - 1))).TotalDays) < int.Parse(item.EndDay)
                                                          )
                                                          .FirstOrDefault();
                if (lateFee == null)//不存在的配置 
                {
                    return 0;
                }
                else
                {
                    //满足条件的最低标准
                    var minlateFeeStand = decimal.Parse(lateFee.LevelStand);
                    if ((ChargeTypeEnum)lateFee.ChargeType == ChargeTypeEnum.LiLv)//计费方式为利率
                    {
                        //计算有效延迟的天数 要减去每月开始的那几天
                        var lateDays = Math.Ceiling((Query.ColetMoneyDate - (Query.ChargeWhichDate.AddMonths(2).AddDays(-Query.ChargeWhichDate.Day).AddDays(lateFee.StartDayOnMonth - 1))).TotalDays);
                        //按照利率计算滞纳金
                        var latePrice = Query.TotalWaterPrice * (decimal)(lateFee.TaxRate) * (decimal)lateDays;
                        //如果没有达到最低标准 则返回最低标准 
                        if (latePrice < minlateFeeStand)
                        {
                            return minlateFeeStand;
                        }
                        else
                        {
                            return latePrice;
                        }
                    }
                    else//计费方式为固定金额
                    {
                        return minlateFeeStand;
                    }
                }
            }
        }

        public void DeleteChargeByChargeName(string chargeName)
        {
            var entity = context.ChargeInfoes.FirstOrDefault(item => item.ChargeName == chargeName && item.State == (int)ChargeInfo.StateEnum.No);
            if (entity != null)
            {
                context.ChargeInfoes.Remove(entity);
                context.SaveChanges();
            }
        }

        public void UpdateChargeInfos(ChargeInfo.StateEnum Stat, ChargeInfo.CollectMoneyTypeEnum? colectType, long? colector, params long[] Ids)
        {
            var entitys = context.ChargeInfoes.Where(item => Ids.Contains(item.Id)).ToList();
            int stat = (int)Stat;
            foreach (var item in entitys)
            {
                item.State = stat;
                item.ColectMoneyDate = DateTime.Now;
                if (colectType != null)
                {
                    item.CollectMoneyType = (int)colectType;
                }
                if (colector != null)
                {
                    item.Collector = colector;
                }



            }
            context.SaveChanges();
        }



        /// <summary>
        /// 获得汇总统计
        /// </summary>
        /// <param name="Query"></param>
        /// <returns></returns>
        public TotalReportModel GetTotalReportModel(TotalReportQuery Query)
        {
            //根据区域计算出用户的个数
            var customerIds = context.Customers.Where(item =>
                                                              (string.IsNullOrEmpty(Query.FirstArea) || item.FirstArea.Contains(Query.FirstArea))
                                                              && (string.IsNullOrEmpty(Query.SecondArea) || item.SecondArea.Contains(Query.SecondArea))
                                                      )
                                                .Select(item => item.Id);

            var ChargeQuery = context.ChargeInfoes.ToList().Where(item => customerIds.Contains(item.CustomId)
                                                               && (Query.dateStart == null || DateTime.Parse(item.ThisTime) >= Query.dateStart)
                                                               && (Query.dateEnd == null || DateTime.Parse(item.ThisTime) <= Query.dateEnd)
                                                         );
            return new TotalReportModel()
            {
                PageModel = new PageModel<ChargeInfo>()
                {
                    Count = ChargeQuery.Count(),
                    Rows = ChargeQuery?.OrderByDescending(item => item.Id).Skip(Query.Skip).Take(Query.PageSize).ToList()
                },
                TotalCustomerCount = customerIds.Count(),
                TotalWaterPrice = ChargeQuery.Sum(item => item.TotalWaterPrice == null ? 0 : item.TotalWaterPrice.Value),
                TotalLateFee = ChargeQuery.Sum(item => item.LateFee == null ? 0 : item.LateFee.Value),
                AmountBeReceived = ChargeQuery.Where(item => item.State == (int)ChargeInfo.StateEnum.No).Sum(item => item.TotalPrice == null ? 0 : item.TotalPrice.Value),
                WaterPriceBeReceived = ChargeQuery.Where(item => item.State == (int)ChargeInfo.StateEnum.No).Sum(item => item.TotalWaterPrice == null ? 0 : item.TotalWaterPrice.Value),
                WaterMuch = (float)ChargeQuery.Sum(item => item.WaterMuch == null ? 0D : item.WaterMuch.Value),
                WaterMuchBeReceived = (float)(ChargeQuery.Where(item => item.State == (int)ChargeInfo.StateEnum.No).Sum(item => item.WaterMuch == null ? 0D : item.WaterMuch.Value)),
                TotalCustomerCountBeReceived = ChargeQuery.Where(item => item.State == (int)ChargeInfo.StateEnum.No).Select(c => c.CustomId).Count(),
                HasColectTotal = ChargeQuery.Where(item => item.State == (int)ChargeInfo.StateEnum.Yes).Sum(item => item.TotalPrice == null ? 0 : item.TotalPrice.Value),

            };
        }
    }
}

